package mytaxis.client.app;

import java.io.BufferedReader;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.text.DecimalFormat;

import mytaxis.client.R;
import mytaxis.client.login.Index;
import mytaxis.client.menu.Menu;
import mytaxis.client.service.ComService;
import mytaxis.client.map.*;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class Price extends Activity {
	
	
	private MyTaxisClientApplication app;
	
	private ComService mBoundService;
	
	private EditText EditAddressSource;
	private EditText EditCitySource;
	private EditText EditAddressDest;
	private EditText EditCityDest;
	private TextView EditPrice;
	private Button BtnCalculate;
	private String addressS;
	private String cityS;
	private String addressD;
	private String cityD;
	private double distance;
	ProgressDialog pd;

	private String URL = "http://maps.google.com/maps/geo?q=";
	
	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
		    mBoundService = ((ComService.LocalBinder)service).getService();
		}
	
		public void onServiceDisconnected(ComponentName className) {
		    mBoundService = null;
		}
		};
	
		Handler mHandler = new Handler() {
			public void handleMessage(Message msg) {
				int result = msg.getData().getInt("result");
				if(result > 0){
					double preu = distance*result;
					DecimalFormat formateador = new DecimalFormat("########.##");
					String p = formateador.format(preu);
					
					EditPrice.setText(p);
				}else{
					if(result == -2)MostrarError("We have no data prices for this city");
					else MostrarError("Error connecting to the server");
				}
				
			};
		};	
		
		private void MostrarError(String error){
			final AlertDialog alertDialog = new AlertDialog.Builder(Price.this).create();
			alertDialog.setTitle("Error");
			alertDialog.setMessage(error);
			alertDialog.setButton("OK", new DialogInterface.OnClickListener() {
				 public void onClick(DialogInterface dialog, int which) {
					 alertDialog.cancel();
				 }
			 });
			alertDialog.show();
		}

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.pricepant);
		startService(new Intent(Price.this, ComService.class));
		bindService(new Intent(this, ComService.class), mConnection, Context.BIND_AUTO_CREATE);
		initViews();
	}

	private void initViews() {

		pd = new ProgressDialog(this);
		EditAddressSource = (EditText) findViewById(R.id.EditAddress1);
		EditCitySource = (EditText) findViewById(R.id.EditCity1);
		EditAddressDest = (EditText) findViewById(R.id.EditAddress2);
		EditCityDest= (EditText) findViewById(R.id.EditCity2);
		EditPrice= (TextView) findViewById(R.id.EditPrice);
		BtnCalculate = (Button) findViewById(R.id.btncalcul);
		
		BtnCalculate.setOnClickListener(new Button.OnClickListener(){
			
			public void onClick(View v) {
				pd.setMessage("Calculating price.");
				pd.setTitle("Price");
				pd.show();
				
				addressS = EditAddressSource.getText().toString();
				cityS = EditCitySource.getText().toString();
				addressS = addressS.replace(" ", "%20");
				cityS = cityS.replace(" ", "%20");
				addressD = EditAddressDest.getText().toString();
				cityD = EditCityDest.getText().toString();
				addressD = addressD.replace(" ", "%20");
				cityD = cityD.replace(" ", "%20");
				
				
				Pair<Double,Double> s = getCoordenades(addressS,cityS);
				Pair<Double,Double> d = getCoordenades(addressD,cityD);
				double posxS = s.first;
				double posyS = s.second;
				double posyD = d.second;
				double posxD = d.first;
				//long -> posx

				distance = calculatedist(posxS,posxD,posyS,posyD);
				
				Thread t = new Thread(new Runnable(){
		    		public void run(){
		    			int res = mBoundService.PreuCiutat(cityS.replace("%20", " "));
	    				Message msg = new Message();
						Bundle b = new Bundle();
						b.putInt("result", res);
						msg.setData(b);
						mHandler.sendMessage(msg);
						pd.dismiss();
		    		}
			});
			t.start();
				
				
			}
			
			private double calculatedist(double posxS,double posxD, double posyS, double posyD){
				double R = 6371;
				double dLat = ((posyD - posyS)* Math.PI )/ 180;
				
				double dLon =( (posxD - posxS)* Math.PI )/ 180;
				double lat1 = posyS*Math.PI / 180;
				double lat2 = posyD* Math.PI / 180;
				
				double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
				        Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) * Math.cos(lat2); 
				double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a)); 
				
				double dist = R*c;
				return dist;
			}
			
		private Pair<Double,Double> getCoordenades(String address, String city){
					
				double posx = 0.0;
				double posy = 0.0;
				String url = URL + address +"%20"+ city + "&output=csv";
				InputStream is = getConnection(url);
				try {
					
					String res = convertToString(is);
					
					String r[] = res.split(",");
					
					if(!r[0].contains("200")){
						MostrarError("Location not found, try again");
						return null;
					}
					else{
						posy = Double.parseDouble(r[2]);
						posx = Double.parseDouble(r[3]);
						}
					
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				return Pair.create(posx, posy);
			}
		
		});
	}  
	
	private String convertToString (InputStream is) throws IOException {
		
		if (is != null) {
			
			Writer writer = new StringWriter();
			
			char[] buffer = new char[1024];

			try {

				Reader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
				int n;
			
			while ((n = reader.read(buffer)) != -1) {
			
			writer.write(buffer, 0, n);
			
			}
			
			} finally {
			
			is.close();
			
			}
			
			return writer.toString();
			
			} else {        
			
			return "";
			
			}
	}
	
	
	private InputStream getConnection(String url) {
		InputStream is = null;
		try {
			URLConnection conn = new URL(url).openConnection();
			is = conn.getInputStream();
			
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return is;
	} 
		
}
